home *** CD-ROM | disk | FTP | other *** search
- /* TrackLocation.c */
- /*
- * Copyright © 1989 Martin Minow. All rights reserved.
- *
- * These routines convert from display (mouse) coordinates
- * to the internal DOT value that designates data.
- *
- * DOT
- * TrackGetOffset(point, track_handle)
- * Point point;
- * TrackHandle track_handle;
- *
- * TrackGetOffset returns the index of the character
- * corresponding to the given point (expressed in
- * window-local coordinates).
- *
- * _Track_mouse_to_dot() Convert window-local mouse
- * coordinates to a character designator.
- * _Track_word() Extend window-local coodinates
- * to designate the start and end of a word.
- * _Track_is_white() Determine if a character is
- * "whitespace".
- * _Track_pixel_row() Locate the row (line of text)
- * that is designated by the mouse vertical loc.
- */
- #include "TrackEdit.h"
- #define TR (*tr)
- #define NIL 0L
-
- DOT
- TrackGetOffset(point, track_handle)
- Point point;
- TrackHandle track_handle;
- {
- register TrackPtr tr;
- _Track_state state;
- DOT result;
-
- tr = _Track_lock(track_handle, &state);
- result =_Track_mouse_to_dot(tr, point);
- _Track_unlock(&state);
- return (result);
- }
-
- /*
- * _Track_mouse_to_dot(mouse)
- * Convert the mouse position (given in window-local
- * coordinates) to an index to the specified character in
- * the string. If the mouse is in the left half of the
- * character, the index refers to the selected character;
- * otherwise it refers to the following character.
- */
- DOT
- _Track_mouse_to_dot(tr, mouse)
- register TrackPtr tr;
- Point mouse;
- {
- register LONGINT row;
- register INTEGER col;
- register int i;
- register DOT dot;
- register DOT next_row;
- register int width;
-
- row = _Track_pixel_row(tr, mouse.v);
- if (row < 0)
- return (0);
- else if (row >= TR.nLines)
- return (TR.textLength);
- else {
- dot = TR.lineStarts[row];
- next_row = TR.lineStarts[row + 1];
- col = mouse.h - _Track_h_origin(tr, row);
- width = 0;
- while (dot < next_row
- && (*TR.hText)[dot] != '\r') {
- width = CharWidth((*TR.hText)[dot]);
- if (col < width)
- break;
- col -= width;
- dot++;
- }
- /*
- * If the mouse is in the right-half of the
- * character, (and it's not at the end of the row),
- * move it forward: note that the DOT value is
- * between two characters.
- */
- if (dot < next_row && col >= (width / 2))
- dot++;
- }
- return (dot);
- }
-
- /*
- * _Track_word(tr, mouse, DOT *, DOT *)
- * Extend dot in both directions to the nearest word
- * boundary. Note that the last character on the line is
- * treated specially. Bug alert: FindWord uses a 16 bit
- * integer for textLength and offset. Thus, as our indices
- * are longs (so we can have a lot of text), we should
- * really fiddle with *hText so FindWord only sees one
- * line of text.
- */
- void
- _Track_word(tr, mouse, word)
- register TrackPtr tr;
- Point mouse;
- _Track_Loc *word;
- {
- register DOT dot;
- register LONGINT row;
- register DOT end;
- OffsetTable offsets;
-
- dot = _Track_mouse_to_dot(tr, mouse);
- if (_Track_is_set(tr, _Track_use_script_manager)) {
- FindWord(
- *TR.hText,
- (INTEGER) TR.textLength,
- (INTEGER) dot,
- TRUE,
- NIL,
- offsets
- );
- #if smgrVers >= 0x0210 /* See ScriptMgr.h */
- /*
- * In Think C version 4, the offset table is defined
- * as a 3-element structure.
- */
- #define START offsets[0].offFirst
- #define END offsets[0].offSecond
- #else
- /*
- * This is specific to Think C version 3, where the
- * offset table is defined as a 6-element short vector.
- * Warning: no longer tested.
- */
- #define START offsets[0]
- #define END offsets[1]
- #endif
- word->start = (DOT) START;
- word->end = (DOT) END;
- }
- else {
- row = _Track_row(tr, dot);
- end = TR.lineStarts[row];
- word->start = dot;
- while (word->start > end
- && !_Track_is_white(
- tr, *(TR.hText), word->start - 1)) {
- --(word->start);
- }
- word->end = dot;
- if (_Track_pixel_row(tr, mouse.v) == row) {
- /*
- * Scan for the whitespace that follows this word.
- * Note that we don't scan if dot has crept into
- * the next line.
- */
- end = TR.lineStarts[row + 1];
- while (word->end < end
- && !_Track_is_white(tr, (*TR.hText), word->end))
- (word->end)++;
- }
- }
- }
-
- /*
- * _Track_is_white(track_pointer, text_pointer, index)
- * Return TRUE if the character at this location is
- * whitespace, calling the application's wordbreak
- * routine if one is present.
- */
- Boolean
- _Track_is_white(tr, ptr, index)
- register TrackPtr tr;
- char *ptr;
- DOT index;
- {
- if (TR.wordBreak == 0)
- return (((unsigned) ptr[index]) <= ' ');
- else {
- return (CallPascalB(ptr, index, TR.wordBreak));
- }
- }
-
- /*
- * Determine the row that contains this mouse location
- * (in window-local coordinates).
- */
- LONGINT
- _Track_pixel_row(tr, vpixel)
- register TrackPtr tr;
- INTEGER vpixel;
- {
- return (
- ((LONGINT) vpixel - TR.viewRect.top + TR.topPixel)
- / TR.lineHeight
- );
- }
-